package com.huiyun.project.pay.biz.controller.pay;

import cn.hutool.core.util.StrUtil;
import com.huiyun.project.common.core.domain.R;
import com.huiyun.project.common.core.util.fn.FunctionUtils;
import com.huiyun.project.common.security.annotation.Inner;
import com.huiyun.project.common.security.util.AssertUtils;
import com.huiyun.project.pay.biz.consts.ErrorConst;
import com.huiyun.project.pay.biz.controller.BaseController;
import com.huiyun.project.pay.biz.dto.PayOrderDto;
import com.huiyun.project.pay.biz.entity.PayChannel;
import com.huiyun.project.pay.biz.handler.pay.AliPayHandler;
import com.huiyun.project.pay.biz.handler.pay.WxPayHandler;
import com.huiyun.project.pay.biz.kit.PayConfigKit;
import com.huiyun.project.pay.biz.service.PayChannelService;
import com.huiyun.project.pay.client.consts.PayConst;
import com.huiyun.project.pay.client.vo.PayReq;
import com.huiyun.project.pay.client.vo.RefundReq;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author tiger
 */
@Controller
@RequestMapping("/pay")
@Api(tags = "多渠道支付接口统一处理")
@AllArgsConstructor
@Slf4j
public class PayController extends BaseController {

    private final AliPayHandler aliPayHandler;
    private final WxPayHandler wxPayHandler;
    private final PayChannelService payChannelService;

    /**
     * 退款
     */
    @RequestMapping(value = "/refund")
    @ResponseBody
    public R<String> tradeRefund(@RequestBody RefundReq refundReq) {
        return FunctionUtils.wrapper(() -> {
            //1.获取此订单的支付渠道
            PayChannel payChannel = payChannelService.getByMchIdAndMchOrderNo(refundReq.getMchId(), refundReq.getMchOrderNo());
            AssertUtils.notNull(payChannel, ErrorConst.PAY_CHANNEL_IS_NULL, ErrorConst.PAY_CHANNEL_IS_NULL_TEXT);
            if (StrUtil.startWith(payChannel.getChannelId(), "WX_")) {
                return R.ok(wxPayHandler.refund(refundReq, payChannel));
            } else {
                return R.ok(aliPayHandler.refund(refundReq, payChannel));
            }
        });
    }


    /**
     * 统一接口下单
     *
     * @param params
     * @return
     */
    @Inner
    @PostMapping(value = "/payOrder/create")
    @ResponseBody
    @ApiOperation("统一下单接口")
    public R payOrder(@RequestBody PayReq params) {
        return FunctionUtils.wrapper(() -> {
            log.debug("-------------[商户统一下单]开始接收统一下单请求 {}-------------", params.getChannelAppId());
            PayConfigKit.init(params.getChannelAppId());
            PayOrderDto payOrderDto = createPayOrder(params);
            String channelId = payOrderDto.getChannelId();
            if (PayConst.PAY_CHANNEL_WX_MINI.equals(channelId)) {
                return wxPayHandler.miniAppPay(payOrderDto);
            } else if (PayConst.PAY_CHANNEL_WX_APP.equals(channelId)) {
                return wxPayHandler.appPay(payOrderDto);
            } else if (PayConst.PAY_CHANNEL_WX_JSAPI.equals(channelId)) {
                return wxPayHandler.mpPay(payOrderDto);
            } else if (PayConst.PAY_CHANNEL_ALIPAY_MOBILE.equals(channelId)) {
                return aliPayHandler.appPay(payOrderDto);
            } else if (PayConst.PAY_CHANNEL_ALIPAY_PC.equals(channelId)) {
                return aliPayHandler.pcPay(payOrderDto);
            } else if (PayConst.PAY_CHANNEL_ALIPAY_WAP.equals(channelId)) {
                return aliPayHandler.wapPay(payOrderDto);
            } else if (PayConst.PAY_CHANNEL_ALIPAY_QR.equals(channelId)) {
                return aliPayHandler.qrPay(payOrderDto);
            } else if (PayConst.PAY_CHANNEL_ALIPAY_BAR.equals(channelId)) {
                return aliPayHandler.barPay(payOrderDto);
            } else {
                return R.failed("不支持的支付渠道类型[channelId=" + channelId + "]");
            }
        });
    }


}
